#ifndef _KLAS_PARTICLE_EMITTER_HPP_
#define _KLAS_PARTICLE_EMITTER_HPP_


#include "../include/Vector2.hpp"
#include "../include/Color.hpp"
#include "../include/Texture.hpp"
#include "../include/Particle.hpp"
#include "../include/Camera.hpp"
#include <vector>
using namespace std;

namespace klas
{
  class Particle;

  //! The particle emits particles based on specified parameters.
  class ParticleEmitter
  {
    public:

      //! Ctor.
      /*! \param posA Particles will be emitted somewhere between posA and posB.
          \param posB Particles will be emitted somewhere between posA and posB.
          \param maxParticles The maximum number of particles that can be in use at any time. */
      ParticleEmitter(const Vector2<Real>& posA, const Vector2<Real>& posB, Real maxParticles);

      //! Dtor.
      ~ParticleEmitter();

      //! Changes the position of where particles are emitted.
      /*! \param posA Particles will be emitted somewhere between posA and posB.
          \param posB Particles will be emitted somewhere between posA and posB. */
      void setPos(const Vector2<Real>& posA, const Vector2<Real>& posB);

      //! Changes the texture of generated particles.
      /*! \param texture The new texture for generated particles. */
      void setTexture(void* texture);

      //! Changes the initial and end colors of generated particles.
      /*! \param initial The initial color of the particle.
          \param final The final color of the particle. */
      void setColors(const Color& initial, const Color& final);

      //! Changes the range at which new velocities are picked for new particles.
      /*! \param min The minimum velocity of new particles.
          \param max The maximum velocity of new particles. */
      void setVelocities(const Vector2<Real>& min, const Vector2<Real>& max);

      //! Changes the amount of dampening that particles endure.
      /*! During each update call, the velocity of each particle is multiplied by the dampening factor.
          \param min The minimum amount to dampen each particle by.
          \param max The maximum amount to dampen each particle by. */
      void setDampening(Real min, Real max);

      //! Changes the range of how many new particles are created each time emitParticles() is called.
      /*! \param min The minimum number of particles created when emitParticles() is called.
          \param max The maximum number of particles created when emitParticles() is called.
          \sa emitParticles() */
      void setCreationRate(iReal min, iReal max);

      //! Changes the range of how many seconds each particle lives for.
      /*! \param min The minimum number of seconds that each particle stays alive.
          \param max The maximum number of seconds that each particle stays alive. */
      void setLifeSpan(Real min, Real max);

      //! Changes the range of the scale of new particles.
      /*! \param initialMin The minimum initial scale of each new particle.
          \param initialMax The maximum initial scale of each new particle. 
          \param finalMin The final minimum scale of each particle.
          \param finalMax The final maximum scale of each particle.*/
      void setScale(Real initialMin, Real initialMax, Real finalMin, Real finalMax);

      //! Changes the maximum number of particles that can be emitted by the emitter.
      /*! \param max The maximum number of particles. */
      void setMaxParticles(iReal max);

			//! Renders particles.
			/*! \param cam The camera. */
			void render(const Camera& cam);
			
      //! Updates all of the currently emitted particles.
      /*! \param dt The time since the last call to updateParticles was made. */
      void updateParticles(Real dt);

      //! Gets the number of active particles.
      /*! \return The number of active particles. */
      iReal getParticleCount() const;
      
      //! Should we emit particles?
      /*! \param emit true says "emit particles." */
      void shouldEmit(bool emit);

    private:

      friend class Particle;
      
      bool m_emitParticles;

      //! This function allows particles to tell the emitter that they are dead.
      /*! \param particle The dead particle. */
      void allowReplacement(Particle* particle);


      //! A private struct that offers convient storage.
      template<class T>
      struct Range
      {
        T min, max;
      };
      //! The vector of particles that this emitter will be emitting.
      vector<Particle> m_particles; 
      
      //! The texture to place on particles.
      Texture* m_texture;

      //! The initial color of particles.
      Color m_initialCol,

      //! The final color of particles.
            m_endCol;

      //! The velocity of particles.
      Range<Vector2<Real> > m_velocity,
      
      //! The position of the emitter.
                            m_emitterPos;

      //! The amount of dampening that is applied to particles velocities.
      Range<Real> m_dampening,

      //! The number of particles created each time emitParticles() is called.
            m_creationRate,

      //! The amount of time that each particle is alive.
            m_lifeSpan,

      //! The intial size of each particle.
            m_initialScale,
            
      //! The final size of each particle.
            m_finalScale;

      //! The maximum number of particles that this emitter can emit.
      iReal m_maxParticles,

      //! The number of active particles
            m_activeParticles;

      
      

  };
}

#endif
